package net.sudot.chess.business.model.enums;

import net.sudot.chess.business.service.system.DefaultProcessStrategy;
import net.sudot.chess.business.service.system.SystemConfigProcessStrategy;
import net.sudot.chess.business.service.system.WechatMediaProcessStrategy;
import net.sudot.commons.json.JsonUtils;

import java.time.Instant;


/**
 * 系统参数配置类型
 *
 * @author tangjialin on 2018-06-09.
 */
public enum SystemConfigType {
    /**
     *
     */
    STRING("字符串") {
        @Override
        public Object deserialize(String value, Class<?> type) {
            if (type == String.class) { return value; }
            return JsonUtils.toObject(value, type);
        }

        @Override
        public String serialize(Object value, Class<?> type) {
            return String.valueOf(value);
        }
    },
    DATE("时间") {
        @Override
        public Object deserialize(String value, Class<?> type) {
            return Instant.ofEpochMilli(Long.parseLong(value));
        }

        @Override
        public String serialize(Object value, Class<?> type) {
            if (value instanceof Instant) {
                return String.valueOf(((Instant) value).toEpochMilli());
            }
            return value.toString();
        }
    },
    ENUM("枚举") {
        @SuppressWarnings("unchecked")
        @Override
        public Object deserialize(String value, Class type) {
            return Enum.valueOf(type, value);
        }

        @Override
        public String serialize(Object value, Class<?> type) {
            return String.valueOf(value);
        }
    },
    WECHAT_MEDIA("微信素材", WechatMediaProcessStrategy.class) {
        @Override
        public Object deserialize(String value, Class<?> type) {
            return JsonUtils.toObject(value, type);
        }

        @Override
        public String serialize(Object value, Class<?> type) {
            return String.valueOf(value);
        }
    };

    private String remark;
    private Class<? extends SystemConfigProcessStrategy> strategy;

    SystemConfigType(String remark) {
        this.remark = remark;
        this.strategy = DefaultProcessStrategy.class;
    }

    SystemConfigType(String remark, Class<? extends SystemConfigProcessStrategy> strategy) {
        this.remark = remark;
        this.strategy = strategy;
    }

    public Class<? extends SystemConfigProcessStrategy> strategy() {
        return strategy;
    }

    public String remark() {
        return remark;
    }

    public abstract Object deserialize(String value, Class<?> type);

    public abstract String serialize(Object value, Class<?> type);
}
